package com.sq.universe.system.controller;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import  com.sq.universe.base.controller.BaseController;
import  com.sq.universe.base.entity.RespEntity;
import  com.sq.universe.system.entity.FileEntity;
import com.sq.universe.system.entity.FileLogEntity;
import com.sq.universe.system.entity.UserEntity;
import com.sq.universe.system.service.FileLogService;
import  com.sq.universe.system.service.FileService;
import com.sq.universe.system.utils.FastDFSClientWrapper;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;

@RestController
@RequestMapping("/file")
@CrossOrigin
public class FileController extends BaseController {

    @Autowired
    private FileService fileService;

    @Autowired
    private FastDFSClientWrapper fastDFSClientWrapper;

    @Autowired
    private FileLogService fileLogService;
    /**
    * 查询数据
    * @param fileEntity
    * @return
    */
    @PostMapping("/query")
    @RequiresPermissions("system:file:query")
    public RespEntity query(FileEntity fileEntity){
        try {
            return new RespEntity("查询成功",fileService.query(fileEntity));
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("查询失败");
        }
    }

    /**
    * 分页查询
    * @param fileEntity
    * @return
    */
    @PostMapping("/queryByPage")
    @RequiresPermissions("system:file:queryByPage")
    public RespEntity queryByPage(FileEntity fileEntity){
        try {
            PageHelper.startPage(fileEntity.getPageNo(),fileEntity.getPageSize());
            List<FileEntity> fileList = fileService.query(fileEntity);
            PageInfo<FileEntity> pageInfo = new PageInfo<FileEntity>(fileList);
            return new RespEntity("查询成功",pageInfo);
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("查询失败");
        }
    }

    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public RespEntity upload(MultipartFile file,Integer fcId) {
        FileEntity fileEntity = fileService.upload(file,this.getCurrentUser(),fcId);
        return new RespEntity("上传成功",fileEntity);
    }

    /**
     * 系統生成的文件
     * @param file
     * @param user
     * @param fcId
     * @return
     */
    @PostMapping("/uploadBySystem")
    public FileEntity uploadBySystem(@RequestPart("file") MultipartFile  file,  @RequestParam("fcId") Integer fcId) {
        FileEntity fileEntity = fileService.upload(file,new UserEntity(),fcId);
        return fileEntity;
    }

    /**
     * 获取文件字节
     * @param fileId
     * @param response
     * @return
     */
    @RequestMapping("/getByte")
    public byte[] getByte(Integer fileId, HttpServletResponse response) {
        FileEntity fileEntity = fileService.getById(fileId);
        return fileService.downLoad(fileEntity);
    }



    /**
     * 文件上传
     * @param fileId
     * @return
     */
//    @PostMapping("/download")
//    public RespEntity download(Integer fileId) {
//        FileEntity fileEntity = fileService.getById(fileId);
//        return new RespEntity("查询成功",fileEntity);
//    }

    @RequestMapping("/download")
    public void download(Integer fileId, HttpServletResponse response) {
        FileEntity fileEntity = fileService.getById(fileId);
        try {

            // 获取文件名
            String filename = fileEntity.getFileName();
            // 获取文件后缀名
            String ext = fileEntity.getFileSuffix();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + fileEntity.getFileSize().intValue());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(fileService.downLoad(fileEntity));
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 保存文件
     * @param request
     * @return
     * @throws IOException
     */
    @RequestMapping(path = "/saveModify")
    @ResponseBody
    public Map saveModify(HttpServletRequest request, HttpServletResponse response) throws IOException {
        Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
        String body = scanner.hasNext() ? scanner.next() : "";
        JSONObject jsonObj = (JSONObject) JSONObject.parse(body);
        if(jsonObj != null && (Integer) jsonObj.get("status") == 2) {
            String downloadUri = (String) jsonObj.get("url");
            String key = ((String) jsonObj.get("key")).split("_")[0];
            String userToken = jsonObj.getJSONArray("users").get(0).toString();
            UserEntity currentUser = this.getUserByToken(userToken);
            FileEntity fileEntity = fileService.getById(Integer.valueOf(key));
            URL url = new URL(downloadUri);
            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
            InputStream stream = connection.getInputStream();
            byte[] bytes = IOUtils.toByteArray(stream);
            // 插入变更日志
            FileLogEntity fileLogEntity = new FileLogEntity();
            fileLogEntity.setFlFileId(fileEntity.getFileId());
            fileLogEntity.setFlName(fileEntity.getFileName());
            fileLogEntity.setFlSize(fileEntity.getFileSize());
            fileLogEntity.setFlPath(fileEntity.getFilePath());
            fileLogEntity.setFlCreateTime(new Date());
            fileLogEntity.setFlCreateUser(currentUser.getUserId());
            fileLogService.insert(fileLogEntity);

            String filePath = fastDFSClientWrapper.uploadFile(bytes,fileEntity.getFileSuffix().replace(".",""));
            fileEntity.setFilePath(filePath);
            fileEntity.setFileSize(Double.valueOf(bytes.length));
            fileService.update(fileEntity);
            connection.disconnect();
        }
        Map map = new HashMap();
        map.put("error","0");
        return map;
    }

    /**
    * 插入
    * @param fileEntity
    * @return
    */
    @PostMapping("/insert")
    @RequiresPermissions("system:file:insert")
    public RespEntity insert(FileEntity fileEntity){
        try {
            fileEntity.setFileCreateTime(new Date());
            fileEntity.setFileCreateUser(this.getCurrentUser().getUserId());
            fileService.insert(fileEntity);
            return new RespEntity("保存成功");
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("保存失败");
        }
    }

    /**
    * 更新
    * @param fileEntity
    * @return
    */
    @PostMapping("/update")
    @RequiresPermissions("system:file:update")
    public RespEntity update(FileEntity fileEntity){
        try {
            fileEntity.setFileUpdateTime(new Date());
            fileEntity.setFileUpdateUser(this.getCurrentUser().getUserId());
            fileService.update(fileEntity);
            return new RespEntity("更新成功");
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("更新失败");
        }
    }


    /**
    * 删除成功
    * @param fileEntity
    * @return
    */
    @PostMapping("/delete")
    @RequiresPermissions("system:file:delete")
    public RespEntity delete(FileEntity fileEntity){
        try {
            if(fileEntity.getFileId() == null){
                return new RespEntity("删除失败");
            }
            fileEntity.setFileUpdateTime(new Date());
            fileEntity.setFileUpdateUser(this.getCurrentUser().getUserId());
            fileService.logicalDelete(fileEntity);
            return new RespEntity("删除成功");
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("删除失败");
        }
    }

    /**
    * 根据ID查询
    * @param fileEntity
    * @return
    */
    @PostMapping("/getById")
    @RequiresPermissions("system:file:getById")
    public RespEntity getById(FileEntity fileEntity){
        try {
            if(fileEntity.getFileId() == null){
                return new RespEntity("请输入id查询");
            }
            return new RespEntity("查询成功",fileService.getById(fileEntity.getFileId()));
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("查询失败");
        }
    }

    /**
    * 根据实体查询
    * @param fileEntity
    * @return
    */
    @PostMapping("/get")
    @RequiresPermissions("system:file:get")
    public RespEntity get(FileEntity fileEntity){
        try {
            return new RespEntity("查询成功",fileService.get(fileEntity));
        }catch (Exception exception){
            exception.printStackTrace();
            return new RespEntity("查询失败");
        }
    }
}